﻿using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;
using VH.SharePoint.Api.Entensions;
using VH.SharePoint.Api.Helpers;

namespace VH.SharePoint.Api
{
    public class PostItem : BlogItem, IPostItemInfo
    {
        private bool IsSitePage {
            get { return this.Item.ContentTypeId.IsChildOf(SPBuiltInContentTypeId.WikiDocument); }
        }
        private bool IsPublishingPage
        {
            get { return PublishingPage.IsPublishingPage(this); }
        }

        public bool Published {
            get { 
                if(Item.ParentList.EnableMinorVersions)
                    return Item.Versions[Item.Versions.Count - 1].Level == SPFileLevel.Published;
                return true;
            }
        }

        public PostItemStatus Status {
            get
            {
                var status = Item.File.Level == SPFileLevel.Published ? PostItemStatus.Published : PostItemStatus.Draft;
                status |= Item.ModerationInformation == null
                              ? PostItemStatus.Approved
                              : (Item.ModerationInformation.Status == SPModerationStatusType.Approved
                                     ? PostItemStatus.Approved
                                     : Item.ModerationInformation.Status == SPModerationStatusType.Denied
                                           ? PostItemStatus.Rejected
                                           : PostItemStatus.WaitingApproval);
                
                return status;
            }
        }

        public new String Title {
            get
            {
                return IsSitePage ? 
                           Item.GetFieldValue<String>(SPBuiltInFieldId.FileLeafRef).Replace(".aspx","")
                           : base.Title;
            }
            set
            {
                if (IsSitePage)
                {
                    SetFieldValue(SPBuiltInFieldId.FileLeafRef,value + ".aspx");
                }
                else
                {
                    base.Title = value;
                }
            }
        }

        public string Content {
            get
            {
                if (IsPublishingPage)
                    return PageHelper.GetHtmlUrlAbsoluteContent(GetFieldValue<string>(FieldId.PublishingPageContent),this.Item.Web.Site);
                if (IsSitePage)
                    return WikiPageHelper.GetHtmlEditableContent(GetFieldValue<string>(SPBuiltInFieldId.WikiField));
                throw new NotSupportedException("The page type is not supported!");
            }
            set
            {
                var html = PageHelper.SetDefaultMarkupStyles(value);
                if (IsPublishingPage)
                {
                    SetFieldValue(FieldId.PublishingPageContent, html);
                    return;
                }
                if (IsSitePage)
                {
                    SetFieldValue(SPBuiltInFieldId.WikiField,
                                  string.IsNullOrEmpty(Content)
                                      ? WikiPageHelper.InsertSharepointHtmlWrapper(html)
                                      : html);
                    return;
                }
                throw new NotSupportedException("The page type is not supported!");
            }
        }

        private void SetFieldValue(Guid fieldId, object value)
        {
            //EnsureCheckedOut();
            Item.SetFieldValue(value, fieldId);
        }

        private T GetFieldValue<T>(Guid fieldId)
        {
            //return (T) Convert.ChangeType(Item[fieldId], typeof (T));
            return Item.GetFieldValue<T>(fieldId);
        }

        private void EnsureCheckedOut()
        {
            using (new SPUnsafeUpdate(Item.Web))
            {
                if (IsPublishingPage || Item.ParentList.EnableVersioning || Item.ParentList.ForceCheckout)
                {
                    if (Item.File.CheckOutType != SPFile.SPCheckOutType.None)
                        Item.File.CheckIn("");
                    Item.File.CheckOut();
                }
            }
        }
        private void EnsureCheckedIn()
        {
            if ((IsPublishingPage || Item.ParentList.EnableVersioning || Item.ParentList.ForceCheckout) &&
                Item.File.CheckOutType != SPFile.SPCheckOutType.None)
            {
                Item.File.CheckIn("", Item.ParentList.EnableMinorVersions?SPCheckinType.MinorCheckIn : SPCheckinType.MajorCheckIn);
            }
        }

        internal void Publish()
        {
            using (new SPUnsafeUpdate(Item.Web))
            {
                EnsureCheckedIn();

                if (Item.ParentList.EnableMinorVersions && Item.File.CheckOutType != SPFile.SPCheckOutType.Online)
                {
                    
                    Item.File.Publish("");
                }
            }
        }

        internal void CheckIn()
        {
            EnsureCheckedIn();
        }

        internal void CheckOut()
        {
            EnsureCheckedOut();
        }

        internal PostItem(SPListItem item) : base(item)
        {
        }
        public static implicit operator PostItem(SPListItem item)
        {
            return new PostItem(item);
        }
        public static implicit operator PostItem(PublishingPage item)
        {
            return new PostItem(item.ListItem);
        }
    }
}